package com.navinfo.platform.basicdatastatistics.service.impl.huashen;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.navinfo.platform.basicdatastatistics.dto.AbstractBasicDataDto;
import com.navinfo.platform.basicdatastatistics.dto.AltitudeDto;
import com.navinfo.platform.basicdatastatistics.dto.VehicleHourInfoDto;
import com.navinfo.platform.basicdatastatistics.dto.yiqi.CustomDto;
import com.navinfo.platform.basicdatastatistics.enums.DataTypeEnum;
import com.navinfo.platform.basicdatastatistics.enums.YardEnum;
import com.navinfo.platform.basicdatastatistics.service.IDataStatisticsService;
import com.navinfo.platform.basicdatastatistics.service.impl.DefaultDataStatisticsService;
import com.navinfo.platform.common.anno.RunningEnv;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.types.DataTypes;
import org.apache.spark.sql.types.Metadata;
import org.apache.spark.sql.types.StructField;
import scala.collection.mutable.WrappedArray;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RunningEnv(yard = YardEnum.HUASHEN, dataType = DataTypeEnum.DAY, interfaceClass = IDataStatisticsService.class)
public class DayDataStatisticsService extends DefaultDataStatisticsService {

    @Override
    public List<StructField> getCustomSchemas() {
        List<StructField> list = new ArrayList<>();
        list.add(new StructField("run_days", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("odo_mileage", DataTypes.LongType, true, Metadata.empty()));
        list.add(new StructField("national_road_mileage", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("national_road_duration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("provincial_road_mileage", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("provincial_road_duration", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("other_road_mileage", DataTypes.IntegerType, true, Metadata.empty()));
        list.add(new StructField("other_road_duration", DataTypes.IntegerType, true, Metadata.empty()));
        return list;
    }

    @Override
    public List<Object> getCustomValues(AbstractBasicDataDto abstractBasicDataDto) {
        CustomDto customDto = (CustomDto) abstractBasicDataDto.getCustomDto();
        List<Object> list = new ArrayList<>();
        list.add(getIntValue(abstractBasicDataDto.getRunDays()));
        list.add(abstractBasicDataDto.getOdoMileage());
        list.add(null);
        list.add(null);
        list.add(null);
        list.add(null);
        list.add(null);
        list.add(null);
        return list;
    }

    @Override
    public void setCustomInfo(Row row, AbstractBasicDataDto abstractBasicDataDto) {
        CustomDto customDto = new CustomDto();
        customDto.setCustomDtoInfo(row);
        abstractBasicDataDto.setCustomDto(customDto);
//        BasicDataDto basicDataDto = (BasicDataDto) abstractBasicDataDto;
//        basicDataDto.setRunDays(row.getAs("run_days"));
    }

    @Override
    public void calcAltitudeInfo(Row row, AbstractBasicDataDto basicDataDto) {
        WrappedArray.ofRef array = row.getAs("altitude_ranges");
        if (array == null) {
            return;
        }
        scala.collection.Iterator<String> altitudeItor = array.iterator();
        TypeReference<Map<String, AltitudeDto>> types = new TypeReference<Map<String, AltitudeDto>>() {
        };
        Map<String, AltitudeDto> altitudeDtoMap = new HashMap<>();
        while (altitudeItor.hasNext()) {
            String altitude = altitudeItor.next();
            Map<String, AltitudeDto> altitudeTempMap = JSON.parseObject(altitude, types);
            altitudeTempMap.forEach((key, value) -> {
                String askKey = "asl" + key;
                AltitudeDto altitudeDto = altitudeDtoMap.get(askKey);
                if (altitudeDto == null) {
                    altitudeDto = new AltitudeDto();
                    altitudeDtoMap.put(askKey, altitudeDto);
                }
                altitudeDto.setFuel(altitudeDto.getFuel() + value.getFuel());
                altitudeDto.setMileage(altitudeDto.getMileage() + value.getMileage());
                altitudeDto.setTime(altitudeDto.getTime() + value.getTime());
            });
        }

        if (altitudeDtoMap.isEmpty()) {
            return;
        }
        basicDataDto.setAltitudeDtoMap(altitudeDtoMap);
    }

    @Override
    public void calcVehicleHourInfo(Row row, AbstractBasicDataDto basicDataDto) {
        WrappedArray.ofRef array = row.getAs("clock_ranges");
        if(array == null){
            return;
        }
        scala.collection.Iterator<String> clockRangesItor = array.iterator();
        TypeReference<Map<String, VehicleHourInfoDto.VehicleHourBean>> types = new TypeReference<Map<String, VehicleHourInfoDto.VehicleHourBean>>(){};
        Map<String, VehicleHourInfoDto.VehicleHourBean> vehicleHourBeanMap = new HashMap<>();
        VehicleHourInfoDto vehicleHourInfoDto = new VehicleHourInfoDto();
        while(clockRangesItor.hasNext()){
            String hour = clockRangesItor.next();
            Map<String, VehicleHourInfoDto.VehicleHourBean> vehicleHourBeanMapFromJson = JSON.parseObject(hour, types);
            vehicleHourBeanMapFromJson.forEach((key, value) -> {
                String hourKey = "hour" + key;
                VehicleHourInfoDto.VehicleHourBean vehicleHourBean = vehicleHourBeanMap.get(hourKey);
                if (vehicleHourBean == null) {
                    vehicleHourBean = new VehicleHourInfoDto.VehicleHourBean();
                    vehicleHourBean.setState(1);
                    vehicleHourBeanMap.put(hourKey, vehicleHourBean);
                }

                vehicleHourBean.accumulationTime(value.getTime());
                vehicleHourBean.accumulationMileage(value.getMileage());
                vehicleHourBean.accumulationFuel(value.getFuel());
            });
        }
        vehicleHourInfoDto.setVehicleHourBeanMap(vehicleHourBeanMap);
        basicDataDto.setVehicleHourInfoDto(vehicleHourInfoDto);
    }

}
